---
import { useTranslations } from '~/i18n/util';
import UIString from '../UIString.astro';
import houston from './houston-happy.webp';
import { Icon } from '@astrojs/starlight/components';

const t = useTranslations(Astro);

const categories = [
	{
		category: 'issue',
		icon: `M12 16a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm10.67 1.47-8.05-14a3 3 0 0 0-5.24 0l-8 14A3 3 0 0 0 3.94 22h16.12a3 3 0 0 0 2.61-4.53Zm-1.73 2a1 1 0 0 1-.88.51H3.94a1 1 0 0 1-.88-.51 1 1 0 0 1 0-1l8-14a1 1 0 0 1 1.78 0l8.05 14a1 1 0 0 1 .05 1.02v-.02ZM12 8a1 1 0 0 0-1 1v4a1 1 0 0 0 2 0V9a1 1 0 0 0-1-1Z`,
	},
	{
		category: 'idea',
		icon: `M17.09 2.82A8 8 0 0 0 5.86 14.13c.7.8 1.1 1.8 1.14 2.87v3a3 3 0 0 0 3 3h4a3 3 0 0 0 3-3v-2.81c.03-1.17.46-2.3 1.22-3.19a8 8 0 0 0-1.13-11.2v.02ZM15 20a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1v-1h6v1Zm1.67-7.24c-1 1.2-1.6 2.68-1.67 4.24h-2v-3a1 1 0 0 0-2 0v3H9a6.5 6.5 0 0 0-1.6-4.16 6 6 0 1 1 9.27-.08Z`,
	},
	{
		category: 'other',
		icon: `M12 10a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-7 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm14 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Z`,
	},
] as const;

const instanceId = Math.round(Math.random() * 10e9).toString(36);
---

<feedback-form>
	<button data-open-modal disabled>
		<UIString key="feedback.button" />
	</button>

	<dialog style="padding:0" aria-label={t('feedback.a11yLabel')}>
		<div class="dialog-frame">
			<button data-close-modal>
				<span class="sr-only"><UIString key="feedback.close" /></span>
				<Icon name="close" size="2em" />
			</button>
			<div class="select-pane" tabindex="-1">
				<h1><UIString key="feedback.formTitle" /></h1>
				<div class="select-buttons">
					<a
						class="github-button"
						href="https://github.com/withastro/docs/issues/new"
						target="_blank"
						rel="noopener noreferrer"
					>
						<Icon name="github" size="4" />
						<h2>
							<UIString key="feedback.createIssue" />
						</h2>
						<p>
							<UIString key="feedback.createIssue.description" />
						</p>
					</a>
					<button data-select-feedback>
						<Icon name="warning" size="4" />
						<h2>
							<UIString key="feedback.sendFeedback" />
						</h2>
						<p>
							<UIString key="feedback.sendFeedback.description" />
						</p>
					</button>
				</div>
			</div>
			<form hidden>
				<button data-back-button>
					<span class="sr-only"><UIString key="feedback.close" /></span>
					<Icon name="left-arrow" size="1em" />
				</button>
				<h1><UIString key="feedback.sendFeedback" /></h1>
				<fieldset class="category-options">
					<legend class="sr-only"><UIString key={'feedback.categoryGroupLabel'} /></legend>
					{
						categories.map(({ category, icon }, index) => (
							<span class="category-option">
								<input
									class="sr-only"
									id={category + instanceId}
									type="radio"
									name="category"
									value={category}
									checked={index === 0}
								/>
								<label for={category + instanceId}>
									<svg
										aria-hidden="true"
										xmlns="http://www.w3.org/2000/svg"
										fill="currentcolor"
										viewBox="0 0 24 24"
									>
										<path d={icon} />
									</svg>
									<span>
										<UIString key={`feedback.${category}`} />
									</span>
								</label>
							</span>
						))
					}
				</fieldset>
				<label for={'textarea' + instanceId} class="sr-only">
					<UIString key="feedback.messageA11yLabel" />
				</label>
				<textarea
					id={'textarea' + instanceId}
					name="text"
					cols="34"
					rows="3"
					required
					placeholder={t('feedback.placeholder')}></textarea>
				<button type="submit"><UIString key="feedback.submit" /></button>
				<a
					href="https://astro.build/privacy/"
					style="text-decoration: underline; align-self: start; color: var(--sl-color-text-accent);"
					target="_blank"
					rel="noopener"
				>
					<UIString key="footer.privacyPolicy" />
				</a>
			</form>
			<div class="success-pane" hidden tabindex="-1">
				<img src={houston.src} alt="" width="128" height="128" />
				<p>
					<UIString key="feedback.success" />
				</p>
			</div>
		</div>
	</dialog>
</feedback-form>

<script>
	class FeedbackForm extends HTMLElement {
		constructor() {
			super();

			const openBtn = this.querySelector<HTMLButtonElement>('button[data-open-modal]')!;
			const closeBtn = this.querySelector<HTMLButtonElement>('button[data-close-modal]')!;
			const backBtn = this.querySelector<HTMLButtonElement>('button[data-back-button]')!;
			const submitBtn = this.querySelector<HTMLButtonElement>('button[type="submit"]')!;
			const dialog = this.querySelector('dialog')!;
			const dialogFrame = this.querySelector('.dialog-frame')!;
			const select = this.querySelector<HTMLDivElement>('div.select-pane')!;
			const form = this.querySelector('form')!;
			const success = this.querySelector<HTMLDivElement>('div.success-pane')!;
			const githubButton = this.querySelector<HTMLLinkElement>('a.github-button')!;
			const feedbackButton = this.querySelector<HTMLLinkElement>('button[data-select-feedback]')!;

			const showScreen = (screen: 'select' | 'form' | 'success') => {
				select.hidden = screen !== 'select';
				form.hidden = screen !== 'form';
				success.hidden = screen !== 'success';
				if (!success.hidden) success.focus();
			};

			/** Close the modal if a user clicks outside of the modal. */
			const onWindowClick = (event: MouseEvent) => {
				if (!dialogFrame.contains(event.target as Node)) closeModal();
			};

			const openModal = (event: MouseEvent) => {
				showScreen('select');
				dialog.showModal();
				form.querySelector<HTMLInputElement>('input:checked')?.focus();
				// Prevent click bubbling up and immediately closing the modal again.
				event.stopPropagation();
				window.addEventListener('click', onWindowClick);
			};

			const closeModal = () => {
				dialog.close();
				window.removeEventListener('click', onWindowClick);
			};

			openBtn.addEventListener('click', openModal);
			closeBtn.addEventListener('click', closeModal);
			backBtn.addEventListener('click', () => {
				showScreen('select');
			});

			// Pre-fills the GitHub issue with any message a site visitor has already typed in the message box
			githubButton.addEventListener('click', () => {
				const newIssueUrl = new URL('https://github.com/withastro/docs/issues/new');
				const titles = { issue: '⚠️ Issue', idea: '💡 Idea', other: '🐠 Feedback' };
				if (form.category.value in titles) {
					const title = titles[form.category.value as keyof typeof titles];
					newIssueUrl.searchParams.set('title', title);
				}
				if (form.text.value) newIssueUrl.searchParams.set('body', form.text.value);
				githubButton.href = newIssueUrl.href;
			});

			feedbackButton.addEventListener('click', () => {
				showScreen('form');
			});

			form.addEventListener('submit', async (event) => {
				event.preventDefault();
				// Disable submit button while submitting to guard against re-submits.
				submitBtn.disabled = true;
				try {
					const res = await fetch('https://api.feedback.fish/feedback', {
						method: 'POST',
						headers: { 'Content-Type': 'application/json' },
						body: JSON.stringify({
							projectId: '1b24b5d16c81bd',
							text: form.text.value,
							category: form.category.value,
							metadata: { url: location.pathname.replace(/\/$/, '') },
						}),
					});
					if (!res.ok) throw new Error(res.statusText);
					const data = await res.json();
					if (data.error) throw new Error(data.error);
				} catch (e) {
					console.error('Error submitting feedback form\n', e);
				}
				showScreen('success');
				submitBtn.disabled = false;
				form.reset();
			});

			// Enable the “Give us feedback” button once JS has loaded.
			openBtn.disabled = false;
		}
	}

	customElements.define('feedback-form', FeedbackForm);
</script>

<style>
	feedback-form {
		--feedback-form-padding: 1rem;
		--feedback-form-close-icon-size: 1.5rem;
	}

	dialog {
		font-size: var(--theme-text-base);
		margin: 1.5rem auto auto;
		border: 1px solid var(--sl-color-gray-5);
		border-radius: 0.5rem;
		width: 32rem;
		background-color: var(--sl-color-gray-6);
		box-shadow: var(--sl-shadow-lg);
	}

	@media (max-width: 50rem) {
		dialog {
			width: 26rem;
		}
	}

	@media (min-width: 30em) {
		dialog {
			margin-top: 4rem;
		}
	}

	dialog::backdrop {
		background-color: var(--sl-color-backdrop-overlay);
		backdrop-filter: blur(2px);
	}

	dialog * {
		margin: 0;
	}

	dialog header {
		display: grid;
		grid-template-columns: 1fr auto 1fr;
		gap: 1rem;
	}

	.dialog-frame {
		display: flex;
		flex-direction: column;
		gap: 0.75rem;
		text-align: center;
		padding: var(--feedback-form-padding);
	}

	form {
		display: contents;
	}

	h1 {
		padding: 0 calc(var(--feedback-form-close-icon-size) + var(--feedback-form-padding));
		font-size: var(--sl-text-xl);
		font-weight: bold;
		grid-column: 2 / 3;
	}

	fieldset {
		border: 2px solid var(--sl-color-gray-5);
		border-radius: 0.5rem;
		padding: 0;
	}

	.category-options {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 0.75rem;
	}

	.category-option label {
		display: flex;
		flex-direction: column;
		align-items: center;
		padding: 0.75rem;
		gap: 0.25rem;
		font-size: var(--theme-text-xs);
		font-weight: 600;
		outline: 2px solid transparent;
		border: 2px solid transparent;
		border-radius: 0.5rem;
		cursor: pointer;
	}

	.category-option label:hover {
		background-color: var(--theme-bg-hover);
	}

	.category-option input:checked + label {
		background-color: var(--sl-color-blue-low);
		border-color: var(--sl-color-blue-high);
	}

	dialog *:focus,
	.category-option input:focus + label {
		outline: 2px solid var(--theme-accent-secondary);
	}

	.category-option svg {
		color: var(--sl-color-gray-2);
		width: 2.25rem;
	}

	.category-option input:checked + label svg {
		color: var(--sl-color-white);
	}

	textarea {
		border: 2px solid var(--sl-color-gray-5);
		border-radius: 0.5rem;
		background-color: var(--sl-color-black);
		resize: none;
		line-height: 1.5;
		padding: 0.5rem;
		font-family: inherit;
		font-size: var(--sl-text-xs);
	}

	.select-buttons {
		display: grid;
		grid-template-columns: 50% 50%;
		justify-content: space-between;
		align-items: center;
		margin-top: 1rem;
	}

	.select-buttons > a,
	.select-buttons > button {
		margin: 0;
		padding: 1rem;
		border: 1px solid var(--sl-color-gray-5);
		border-radius: 0.5rem 0 0 0.5rem;
		background-color: transparent;
		height: 100%;
		font-size: var(--sl-text-2xl);
		cursor: pointer;
	}

	.select-buttons > button {
		border-radius: 0 0.5rem 0.5rem 0;
		border-left: none;
	}

	.select-buttons > a:hover,
	.select-buttons > button:hover {
		background-color: var(--sl-color-gray-5);
	}

	.select-buttons h2 {
		color: var(--sl-color-white);
	}

	.select-buttons p {
		font-size: var(--sl-text-xs);
		color: var(--sl-color-gray-2);
	}

	.select-buttons > *:hover > p,
	.select-buttons > *:hover > svg {
		color: var(--sl-color-white);
	}

	@media (max-width: 50em) {
		.select-buttons {
			flex-direction: column;
			align-items: stretch;
		}
	}

	button[type='submit'] {
		background-color: var(--sl-color-white);
		color: var(--sl-color-blue);
		display: flex;
		justify-content: center;
		align-items: center;
		flex: 1;
		font: inherit;
		padding: 0.5rem;
		border-radius: 2rem;
		cursor: pointer;
		font-size: var(--sl-text-sm);
	}

	:root[data-theme='light'] button[type='submit'] {
		color: #fff;
	}

	form:invalid button[type='submit'] {
		opacity: 0.3;
		cursor: not-allowed;
	}

	.success-pane {
		padding: 2rem;
	}

	button[data-close-modal],
	button[data-back-button] {
		position: absolute;
		top: var(--feedback-form-padding);
		right: var(--feedback-form-padding);
		display: flex;
		border: 0;
		padding: 0.125rem;
		background-color: transparent;
		width: var(--feedback-form-close-icon-size);
		justify-self: flex-end;
		color: var(--theme-text-lighter);
		cursor: pointer;
	}

	button[data-back-button] {
		left: var(--feedback-form-padding);
		right: initial;
		border: 1px solid var(--sl-color-white);
		border-radius: 50%;
		width: 2rem;
		height: 2rem;
		padding: calc(0.5rem - 1px) 0.5rem;
	}

	button[data-close-modal]:hover {
		color: var(--theme-text);
	}

	button[data-open-modal] {
		margin-top: 0.5rem;
		border: 1px solid var(--sl-color-gray-1);
		border-radius: 1rem;
		background-color: transparent;
		cursor: pointer;
		font-size: var(--sl-text-xs);
		line-height: calc(1 / var(--theme-text-xs));
		padding: 0.25rem 0.75rem;
	}

	button[data-open-modal]:hover,
	button[data-open-modal]:focus {
		background-color: var(--sl-color-gray-6);
	}

	button[data-open-modal]:focus:not(:focus-visible) {
		background-color: transparent;
	}

	[hidden] {
		display: none;
	}
</style>
